//****************************************************
// Parser
//****************************************************
#include "algebra3.h"
#include <string>
#include <fstream>
#include <sstream>
#include <GL/glut.h>
#include <GL/glu.h>
#include "parser.h"

vec3 faceParser(string line){
	int vert, text, norm, num;
	string temp;
	size_t index;
	
	index = line.find_first_of("/");
	temp = line.substr(0, index);
	vert = atoi(temp.c_str());
	num = index + 1;
	
	index = line.find_first_of("/", num);
	temp = line.substr(num, index);
	text = atoi(temp.c_str());
	num = index + 1;
	
	index = line.find_first_of("/", num);
	temp = line.substr(num, index);
	norm = atoi(temp.c_str());
	
	vec3 retVal = vec3(vert, text, norm);
		
	return retVal;
}

Material getMat(string fileName){
	ifstream file;
	file.open(fileName.c_str());
	
	Material mat;
	
	string current;
	string cmd;
	
	while (getline(file, current)){
		stringstream ss(stringstream::in | stringstream::out);
		ss.str(current);
		
		ss >> cmd;
		if (!cmd.compare("Kd") || !cmd.compare("Ka") || !cmd.compare("Ks") || !cmd.compare("Tf")){
			GLfloat x, y , z;
			
			ss >> x >> y >> z;
			vec3 v = vec3(x,y,z);
			
			if (!cmd.compare("Kd"))
				mat.kd = v;
			if (!cmd.compare("Ka"))
				mat.ka = v;
			if (!cmd.compare("Ks"))
				mat.ks = v;
			if (!cmd.compare("Tf"))
				mat.transparent = v;
		}
		
		if (!cmd.compare("illum") || !cmd.compare("Ns") || !cmd.compare("Ni")){
			float a;
			ss >> a;
			
			if (!cmd.compare("illum"))
				mat.illum = a;
			if (!cmd.compare("Ns"))
				mat.shiny = a;
			if (!cmd.compare("Ni"))
				mat.refract = a;
		}
	}
	
	return mat;
}

Model getInput(string fileName){
	ifstream file;
	file.open(fileName.c_str());
	
	if (file.is_open()){
		cout << "file open" <<endl;
	}
	
	Model m;
	
	string current;
	string cmd;
	vec3 min = vec3(1000, 1000, 1000);
	vec3 max = vec3(-1000, -1000, -1000);
	
	while (getline(file, current)){
		stringstream ss(stringstream::in | stringstream::out);
		ss.str(current);
		
		ss >> cmd;
		if (!cmd.compare("v") || !cmd.compare("vn")){
			float x, y , z;
			
			ss >> x >> y >> z;
			vec3 v = vec3(x,y,z);
			
			if (!cmd.compare("v")){
				m.points.push_back(v);
				
				for (int i = 0; i < 3; i++){
					min[i] = MIN(v[i], min[i]);
					max[i] = MAX(v[i], max[i]);
				}
			}
			
			if (!cmd.compare("vn"))
				m.normals.push_back(v);
		}
		
		if (!cmd.compare("vt")){
			float x, y;
			
			ss >> x >> y;
			vec2 v = vec2(x,y);
			m.textures.push_back(v);
		}
		
		if (!cmd.compare("f")){
			vec3 v1, v2, v3;
			string line;
			
			ss>> line;
			v1 = faceParser(line);
			
			ss>> line;
			v2 = faceParser(line);
			
			ss>> line;
			v3 = faceParser(line);
			
			Face tri = Face(v1, v2, v3);
			
			m.count += 1;
			m.faces.push_back(tri);
		}
	}
	
	m.box = BoundingBox(min, max);
	string fileMtl = fileName.substr(0, (fileName.length() - 3)) + "mtl";
	cout << fileMtl << endl;
	m.mat = getMat(fileMtl);
	
	return m;
}
